#!/usr/bin/env python
# encoding: utf-8
"""
@file: jidinghezuixiao.py
@time: 2016/11/21 上午10:54
"""
# 2.积定和最小 相关题型
from functools import reduce
from mathsolver.functions.base import *
from sympy import fraction, expand
from mathsolver.functions.budengshi import common_opers as co


class JiDingHeZuiXiao001(BaseFunction):
    """
    # 设a>b>0,则{a}^{2}+\\frac{1}{ab}+\\frac{1}{a(a-b)}的最小值是()
    # 设a>2,则a+\\frac{1}{a-2}的最小值是().
    # paramer1:ineq, paramer2: poly
    """
    def solver(self, *args):
        self.label.add('积定和最小')
        arg0 = args[0]
        if isinstance(arg0, BaseIneq):
            l_expr, o, r_expr = arg0.sympify()
            t_f = l_expr - r_expr
            self.steps.append(['\\because ' + arg0.printing(), '\\therefore %s %s 0' % (new_latex(t_f), o)])
        elif isinstance(arg0, BaseIneqs) and list(co.flatten(arg0.value)) == list(arg0.value):
            ineq_v = arg0.value
            ineq_str = ''.join(ineq_v)
            t_f = sympify(ineq_v[0]) - sympify(ineq_v[2])
            self.steps.append(['\\because ' + ineq_str, '\\therefore ' + new_latex(t_f) + '>0'])
        f = args[1].sympify()
        mons = list(map(lambda t: t[0] * t[1], f.as_coefficients_dict().items()))
        de_mons = list(filter(lambda m: not fraction(m)[1].is_real, mons))
        new_mons = list(map(lambda m: fraction(m)[1] + m, de_mons))
        new_f = reduce(lambda a, b: a + b, new_mons)
        other = expand(f) - expand(new_f)
        if not other.is_real:
            raise Exception('Type Match Error')
        f2 = sympify(str(new_f) + '+' + str(other), evaluate=False)
        min_value = 2 * len(de_mons) + other
        self.steps.append(['\\therefore ' + new_latex(f) + '=' + new_latex(f2), '>=' + new_latex(min_value)])
        self.output.append(BaseNumber(min_value))
        return self


class JiDingHeZuiXiao(BaseFunction):
    CLS = [JiDingHeZuiXiao001, ]

    def solver(self, *args):
        res = None
        for cl in JiDingHeZuiXiao.CLS:
            try:
                res = cl(verbose=True).solver(*args)
                break
            except Exception:
                pass
        if not res:
            raise 'try fail'
        return res


if __name__ == '__main__':
    pass
